﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public delegate void CEventListenerDelegate(CBaseEvent evt);
public delegate void CEventListenerDelegateObject(params object[] _sender);

public class EventSystemManager
{
    static EventSystemManager instance;
    public static EventSystemManager Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new EventSystemManager();
            }

            return instance;
        }
    }

    private Hashtable listeners = new Hashtable();

    //实现多播委托
    public void AddEventListener(string eventName, CEventListenerDelegate listener)
    {
        CEventListenerDelegate ceventListenerDelegate = this.listeners[eventName] as CEventListenerDelegate;
        //这个combine就相当于委托的+=    (整体的实现就是类似于观察者模式)
        ceventListenerDelegate = (CEventListenerDelegate)Delegate.Combine(ceventListenerDelegate, listener);
        this.listeners[eventName] = ceventListenerDelegate;
    }

    public void RemoveEventListener(string eventName, CEventListenerDelegate listener)
    {
        CEventListenerDelegate ceventListenerDelegate = this.listeners[eventName] as CEventListenerDelegate;
        if (ceventListenerDelegate != null)
        {
            ceventListenerDelegate = (CEventListenerDelegate)Delegate.Remove(ceventListenerDelegate, listener);
        }
        //this.listeners[eventName] = ceventListenerDelegate;
        this.listeners.Remove(eventName);
    }

    //---------------------------------object参数----------------------------
    public void AddListener(string eventName, CEventListenerDelegateObject listener)
    {
        CEventListenerDelegateObject ceventListenerDelegate = this.listeners[eventName] as CEventListenerDelegateObject;
        //这个combine就相当于委托的+=    (整体的实现就是类似于观察者模式)
        ceventListenerDelegate = (CEventListenerDelegateObject)Delegate.Combine(ceventListenerDelegate, listener);
        this.listeners[eventName] = ceventListenerDelegate;
    }
    public void RemoveListener(string eventName, CEventListenerDelegateObject listener)
    {
        CEventListenerDelegateObject ceventListenerDelegate = this.listeners[eventName] as CEventListenerDelegateObject;
        if (ceventListenerDelegate != null)
        {
            ceventListenerDelegate = (CEventListenerDelegateObject)Delegate.Remove(ceventListenerDelegate, listener);
        }
        //this.listeners[eventName] = ceventListenerDelegate;
        this.listeners.Remove(eventName);
    }
    

    /// <summary>
    /// 使用字符串传递
    /// </summary>
    /// <param name="evt"></param>
    public void DispatchStringEvent(CBaseEvent evt)
    {
        CEventListenerDelegate ceventListenerDelegate = this.listeners[evt.EventName] as CEventListenerDelegate;

        if (ceventListenerDelegate != null)
        {
            try
            {
                ceventListenerDelegate(evt);
            }
            catch (Exception ex)
            {
                throw new Exception(string.Concat(new string[]
                {
                    "Error dispatching event ",
                    ": ",
                    ex.Message,
                    " ",
                    ex.StackTrace
                }), ex);
            }
        }
    }

    public void DispatchCE(string eventName, object data)
    {
        DispatchStringEvent(new CBaseEvent(eventName,data));
    }
    public void DispatchCE(string eventName, object data1, object data2)
    {
        DispatchStringEvent(new CBaseEvent(eventName,data1, data2));
    }
    public void DispatchCE(string eventName, object[] data = null)
    {
        DispatchStringEvent(new CBaseEvent(eventName,data));
    }
    
    public void Dispatch(string name,params object[] data)
    {
        CEventListenerDelegateObject ceventListenerDelegate = this.listeners[name] as CEventListenerDelegateObject;
        ceventListenerDelegate(data);
    }
    
    public void RemoveAll()
    {
        this.listeners.Clear();
    }
}
